package com.dwy2002.user.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dwy2002.common.Result;
import com.dwy2002.common.exception.EmptyIdException;
import com.dwy2002.common.utils.Validator;
import com.dwy2002.enums.Status;
import com.dwy2002.pojo.dto.users.PermissionDTO;
import com.dwy2002.pojo.dto.users.PermissionPageDTO;
import com.dwy2002.pojo.po.users.Permission;
import com.dwy2002.pojo.po.users.RolePermission;
import com.dwy2002.pojo.vo.users.PermissionVO;
import com.dwy2002.user.mapper.PermissionMapper;
import com.dwy2002.user.mapper.RolePermissionMapper;
import com.dwy2002.user.service.IPermissionService;
import com.dwy2002.user.service.IRolePermissionService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;

import static com.dwy2002.common.Result.*;
import static com.dwy2002.common.utils.Utils.*;

/**
 * @author 杜伟毅
 * @version 1.0
 * @since 2025/04/03
 */
@Service
@RequiredArgsConstructor
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {
    private final IRolePermissionService rolePermissionService;
    private final RolePermissionMapper rolePermissionMapper;

    /**
     * 添加权限
     *
     * @param dto 权限 DTO
     * @author 杜伟毅
     * @since 2025/4/3 0003 22:25
     */
    @Override
    public Result<Void> addPermission(PermissionDTO dto) {
        Validator.of(dto)
                .notEmpty(PermissionDTO::getPermCode, "权限标识不能为空")
                .notEmpty(PermissionDTO::getPermName, "权限名称不能为空")
                .mustSatisfy(isPermCodeRepeat(dto.getPermCode()), "权限标识不允许重复")
                .validatePermCodeFormat(dto.getPermCode())
                .validate();

        boolean save = save(BeanUtil.copyProperties(dto, Permission.class));
        return saveResult(save, "添加成功", "添加失败");
    }

    /**
     * 删除权限（根据ID删除）
     *
     * @param ids 权限id集合
     * @author 杜伟毅
     * @since 2025/4/3 0003 22:25
     */
    @Override
    public Result<Void> deletePermission(List<String> ids) {
        if (isListEmpty(ids)) return fail(Status.BAD_REQUEST, "id不允许为空");
        //校验ids是否参在数据库
        List<String> validaIds = list(new LambdaQueryWrapper<Permission>().in(Permission::getId, ids)).stream().map(Permission::getId).toList();
        //删除角色权限关系
        rolePermissionService.deleteRolePermissionByPermIds(validaIds);
        boolean remove = removeByIds(validaIds);
        return handleResult(remove, "删除成功", "删除失败");
    }

    /**
     * 更新权限（根据DTO中的ID更新）
     *
     * @param dto 权限 DTO
     * @author 杜伟毅
     * @since 2025/4/3 0003 22:24
     */
    @Override
    public Result<Void> updatePermission(PermissionDTO dto) {
        Validator.of(dto)
                .notEmpty(PermissionDTO::getId, "id不能为空")
                .notEmpty(PermissionDTO::getPermCode, "权限标识不能为空")
                .notEmpty(PermissionDTO::getPermName, "权限名称不能为空")
                .mustSatisfy(isPermCodeRepeat(dto.getPermCode()), "权限标识不允许重复")
                .validatePermCodeFormat(dto.getPermCode())
                .validate();

        Permission permission = getById(dto.getId());
        if (ObjectUtils.isEmpty(permission)) return fail(Status.BAD_REQUEST, "权限不存在");
        LambdaUpdateWrapper<Permission> luw = new LambdaUpdateWrapper<>();
        luw.eq(Permission::getId, dto.getId())
                .set(!dto.getPermCode().equals(permission.getPermCode()), Permission::getPermCode, dto.getPermCode())
                .set(!dto.getPermName().equals(permission.getPermName()), Permission::getPermName, dto.getPermName())
                .set(!dto.getDescription().equals(permission.getDescription()), Permission::getDescription, dto.getDescription());

        boolean update = update(luw);
        return handleResult(update, "修改成功", "修改失败");
    }

    /**
     * 查询单个权限（根据ID查询）
     *
     * @param id 权限id
     * @author 杜伟毅
     * @since 2025/4/3 0003 22:24
     */
    @Override
    public Result<Permission> getPermissionById(String id) {
        if (isEmptyOrNull(id)) fail(Status.BAD_REQUEST, "id不能为空");
        Permission permission = getById(id);
        if (ObjectUtils.isEmpty(permission)) fail(Status.BAD_REQUEST, "数据不存在");
        return success(permission);
    }

    /**
     * 分页查询权限列表
     *
     * @param dto 权限分页DTO
     * @author 杜伟毅
     * @since 2025/4/3 0003 22:21
     */
    @Override
    public Result<Page<Permission>> getPermissionPage(PermissionPageDTO dto) {
        Validator.of(dto)
                .mustSatisfy(isPageNull(dto.getPageNo(), dto.getPageSize()), "请传入分页数据")
                .mustSatisfy(isPageZero(dto.getPageNo(), dto.getPageSize()), "分页数据不能为0")
                .validate();
        LambdaQueryWrapper<Permission> lqw = new LambdaQueryWrapper<>();
        lqw.like(!isEmptyOrNull(dto.getPermCode()), Permission::getPermCode, dto.getPermCode())
                .like(!isEmptyOrNull(dto.getPermName()), Permission::getPermName, dto.getPermName())
                .likeRight(dto.getPermLevelFilterEnabled(), Permission::getPermCode, dto.getPermLevel())
                .orderBy(dto.getPermCodeEnabled(), dto.getPermCodeIsAsc(), Permission::getPermCode);

        Page<Permission> page = new Page<>(dto.getPageNo(), dto.getPageSize());
        Page<Permission> permissionPage = this.page(page, lqw);
        return success(permissionPage);
    }

    /**
     * 返回权限标识等级
     *
     * @author 杜伟毅
     * @since 2025/4/4 0004 0:28
     */
    @Override
    public Result<List<String>> getPermLevel() {
        LambdaQueryWrapper<Permission> lqw = new LambdaQueryWrapper<>();
        lqw.groupBy(Permission::getPermCode)
                .select(Permission::getPermCode);
        List<String> permLevel = list(lqw).stream()
                .map(Permission::getPermCode)
                .map(p -> String.valueOf(p.charAt(0)))
                .distinct() //去重
                .sorted() //排序
                .toList();
        return success(permLevel);
    }

    /**
     * 根据角色id返回权限代码
     *
     * @param roleId 角色id
     * @return 权限代码集合
     * @author 杜伟毅
     * @since 2025/5/12 0012 21:39
     */
    @Override
    public List<String> getPermCode(String roleId) {
        if (isEmptyOrNull(roleId)) throw new EmptyIdException("getPermCodeByRoleId");

        // 1. 查询角色关联的权限ID列表
        List<String> permissionIds = rolePermissionMapper
                .selectList(new LambdaQueryWrapper<RolePermission>().eq(RolePermission::getRoleId, roleId))
                .stream()
                .map(RolePermission::getPermId)
                .toList();

        // 2. 如果权限ID列表为空，直接返回空集合
        if (isListEmpty(permissionIds)) {
            return Collections.emptyList();
        }

        // 3. 构建查询条件（此时 permissionIds 一定非空）
        LambdaQueryWrapper<Permission> lqw = new LambdaQueryWrapper<>();
        lqw.in(Permission::getId, permissionIds)
                .select(Permission::getPermCode);

        // 4. 执行查询并返回结果
        return list(lqw)
                .stream()
                .map(Permission::getPermCode)
                .toList();
    }

    /**
     * 根据角色id返回权限
     *
     * @param roleId 角色id
     * @return 权限集合
     * @author 杜伟毅
     * @since 2025/5/14 0014 23:46
     */
    @Override
    public List<PermissionVO> getPermission(String roleId) {
        if (isEmptyOrNull(roleId)) throw new EmptyIdException("getPermission");

        // 1. 查询角色关联的权限ID列表
        List<String> permissionIds = rolePermissionMapper
                .selectList(new LambdaQueryWrapper<RolePermission>().eq(RolePermission::getRoleId, roleId))
                .stream()
                .map(RolePermission::getPermId)
                .toList();

        // 2. 如果权限ID列表为空，直接返回空集合
        if (isListEmpty(permissionIds)) {
            return Collections.emptyList();
        }
        // 3. 构建查询条件（此时 permissionIds 一定非空）
        LambdaQueryWrapper<Permission> lqw = new LambdaQueryWrapper<>();
        lqw.in(Permission::getId, permissionIds);

        return BeanUtil.copyToList(list(lqw), PermissionVO.class);
    }

    /**
     * 返回全部权限
     *
     * @author 杜伟毅
     * @since 2025/5/15 0015 0:30
     */
    @Override
    public Result<List<PermissionVO>> getAllPermission() {
        return success(BeanUtil.copyToList(list(new LambdaQueryWrapper<>()), PermissionVO.class));
    }

    //子方法-----------------------------------------------------------------------------------------------------

    /**
     * 检查权限标识是否重复
     *
     * @param permCode 权限标识
     * @return true：重复 false：不重复
     * @author 杜伟毅
     * @since 2025/4/4 0004 0:45
     */
    private boolean isPermCodeRepeat(String permCode) {
        LambdaQueryWrapper<Permission> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Permission::getPermCode, permCode);
        return exists(lqw);
    }
}
